package com.pactera.madp.cp.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pactera.madp.admin.api.vo.SysFileVo;
import com.pactera.madp.common.core.exception.CheckedException;
import com.pactera.madp.common.core.util.R;
import com.pactera.madp.cp.api.bo.ContactUniqueQrCodeBo;
import com.pactera.madp.cp.api.dto.contact.ContactUniqueQrCodeDto;
import com.pactera.madp.cp.api.entity.ContactUniqueQrCode;
import com.pactera.madp.cp.api.entity.CorpEntity;
import com.pactera.madp.cp.api.entity.WorkContactEntity;
import com.pactera.madp.cp.api.entity.WorkEmployeeEntity;
import com.pactera.madp.cp.api.vo.contact.ContactUniqueQrCodeVo;
import com.pactera.madp.cp.api.vo.contact.ContactUniqueQrCodeWebVo;
import com.pactera.madp.cp.common.config.FileUploadConfig;
import com.pactera.madp.cp.common.constant.Constant;
import com.pactera.madp.cp.common.util.RedisUtil;
import com.pactera.madp.cp.common.util.WxApiUtils;
import com.pactera.madp.cp.common.util.file.FilesUtil;
import com.pactera.madp.cp.handler.CorpContextHolder;
import com.pactera.madp.cp.mapper.ContactUniqueQrCodeMapper;
import com.pactera.madp.cp.service.ContactUniqueQrCodeService;
import com.pactera.madp.cp.service.IContactService;
import com.pactera.madp.cp.service.ICorpService;
import com.pactera.madp.cp.service.IWorkEmployeeService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@AllArgsConstructor
public class ContactUniqueQrCodeServiceImpl extends ServiceImpl<ContactUniqueQrCodeMapper, ContactUniqueQrCode> implements ContactUniqueQrCodeService{

    private final ICorpService corpService;
    private final IContactService contactService;
    private final IWorkEmployeeService workEmployeeService;
    private final FileUploadConfig config;

    @Override
    public R getUniqueQrCode(ContactUniqueQrCodeDto dto) {
        //校验操作类型
        Integer operType = dto.getOperType();
        checkOperation(operType);

        Integer corpId = CorpContextHolder.getCorpId();
        String wxUserId = dto.getWxUserId();
        String wxExternalUserid = dto.getWxExternalUserid();

        //获取企业
        CorpEntity corp = corpService.getById(corpId);
        //获取企业成员
        WorkEmployeeEntity employee = workEmployeeService.getWorkEmployeeByCorpIdAndWxUserId(corpId, wxUserId);
        if(employee == null || employee.getStatus() != 1) {
            throw new CheckedException("企业成员不存在");
        }
        Integer employeeId = employee.getId();
        //获取外部联系人
        WorkContactEntity contactEntity = contactService.getOne(Wrappers.<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getWxExternalUserid, wxExternalUserid)
                .eq(WorkContactEntity::getCorpId, corpId), false);
        if(contactEntity == null) {
            throw new CheckedException("外部联系人不存在");
        }
        Integer contactId = contactEntity.getId();

        ContactUniqueQrCodeVo vo = new ContactUniqueQrCodeVo();
        //获取锁
        String lockKey = corpId +"-" + employeeId + "-" + contactId;
        boolean lock = RedisUtil.getLock(lockKey);
        try{
            if(!lock) {
                return R.ok(vo);
            }

            //查询一客一码记录
            ContactUniqueQrCode cuqc = this.getOne(Wrappers.<ContactUniqueQrCode>lambdaQuery()
                    .eq(ContactUniqueQrCode::getEmployeeId, employeeId)
                    .eq(ContactUniqueQrCode::getContactId, contactId), false);

            Map result = null;
            String state = "";
            if(cuqc == null) {
                //没有记录则生成联系我二维码,这里使用邀请客户、企业成员主键id作为专属二维码标识state
                state = Constant.UQC_PREFIX + contactId + "-" + employeeId;
                result = generateLocalQrCode(corpId, wxUserId, state, vo);
            } else {
                //已存在直接获取
                result = getLocalQrCode(cuqc, corpId, vo);
            }

            boolean isChangeQrCode = (boolean)result.get("isChangeQrCode");
            String localQrCode = (String)result.get("localQrCode");
            String configId = (String)result.get("configId");

            boolean isChangeUnique = false;
            String uniqueQrCode = "";

            ContactUniqueQrCodeBo bo = new ContactUniqueQrCodeBo();
            bo.setName(employee.getName());
            bo.setAvatar(employee.getAvatar());
            bo.setCompany(corp.getCorpName());
            bo.setLocalQrCode(localQrCode);
            bo.setDesc("扫一扫，加我企业微信");
            bo.setFileKey(cuqc == null ? "" : cuqc.getUniqueQrCode().replace(config.getAccessPath(),""));
            //判断操作类型
            if(operType == 1) {
                //更新头像重新生成客户专属二维码
                uniqueQrCode = generateUniqueQrCode(bo);
                isChangeUnique = Boolean.TRUE;
            } else {
                //查询客户专属二维码
                if(cuqc == null) {
                    uniqueQrCode = generateUniqueQrCode(bo);
                    isChangeUnique = Boolean.TRUE;
                } else {
                    uniqueQrCode = cuqc.getUniqueQrCode();
                    //校验二维码文件是否存在
                    File uniqueQrCodeFile = FilesUtil.getFileByURI(uniqueQrCode);
                    if(!uniqueQrCodeFile.exists()) {
                        //不存在重新生成
                        uniqueQrCode = generateUniqueQrCode(bo);
                        isChangeUnique = Boolean.TRUE;
                    }
                }
            }

            //上传客户专属二维码至临时素材
            String mediaId = null;
            if(isChangeUnique) {
                File uniqueFile = FilesUtil.getFileByURI(uniqueQrCode);
                mediaId = WxApiUtils.uploadImageToTemps(corpId, uniqueFile,"image");
            }

            boolean flag = false;
            if(cuqc == null) {
                //初次创建
                cuqc = new ContactUniqueQrCode();
                cuqc.setContactId(contactId);
                cuqc.setEmployeeId(employeeId);
                cuqc.setConfigId(configId);
                cuqc.setLocalQrCode(localQrCode);
                cuqc.setState(state);
                cuqc.setUniqueQrCode(uniqueQrCode);
                cuqc.setMediaId(mediaId);
                flag = this.save(cuqc);
            }else {
                //更新
                if(isChangeQrCode || isChangeUnique) {
                    cuqc.setLocalQrCode(localQrCode);
                    cuqc.setUniqueQrCode(uniqueQrCode);
                    cuqc.setMediaId(mediaId);
                    flag = this.updateById(cuqc);
                }else {
                    //仅查询
                    //校验mediaId是否过期,过期则重新上传
                    String respJson = WxApiUtils.getFromTemp(corpId, mediaId);
                    if(respJson == null) {
                        File uniqueFile = FilesUtil.getFileByURI(cuqc.getUniqueQrCode());
                        mediaId = WxApiUtils.uploadImageToTemps(corpId, uniqueFile,"image");
                        cuqc.setUniqueQrCode(mediaId);
                        flag = this.updateById(cuqc);
                    }else {
                        flag = Boolean.TRUE;
                    }
                }

            }

            vo.setUniqueQrCode(uniqueQrCode);
            vo.setMediaId(mediaId);
            if(!flag) {
                vo.setUniqueQrCode("");
                log.error("创建专属二维码失败");
            }
        }catch (Exception e) {
            log.error("创建专属二维码失败",e);
        }
        finally {
            if(lock) {
                //释放锁
                RedisUtil.del(lockKey);
            }
        }

        return R.ok(vo);
    }

    @Transactional(rollbackFor = Exception.class)
    public R getUniqueQrCode1(ContactUniqueQrCodeDto dto) {
        //校验操作类型
        Integer operType = dto.getOperType();
        checkOperation(operType);

        Integer corpId = CorpContextHolder.getCorpId();
        String wxUserId = dto.getWxUserId();
        String wxExternalUserid = dto.getWxExternalUserid();

        //获取企业
        CorpEntity corp = corpService.getById(corpId);
        //获取企业成员
        WorkEmployeeEntity employee = workEmployeeService.getWorkEmployeeByCorpIdAndWxUserId(corpId, wxUserId);
        if(employee == null || employee.getStatus() != 1) {
            throw new CheckedException("企业成员不存在");
        }
        Integer employeeId = employee.getId();
        //获取外部联系人
        WorkContactEntity contactEntity = contactService.getOne(Wrappers.<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getWxExternalUserid,wxExternalUserid)
                .eq(WorkContactEntity::getCorpId,corpId),false);
        if(contactEntity == null) {
            throw new CheckedException("外部联系人不存在");
        }
        Integer contactId = contactEntity.getId();

        ContactUniqueQrCodeVo vo = new ContactUniqueQrCodeVo();
        vo.setEmpName(employee.getName());
        vo.setAvatar(employee.getAvatar());
        vo.setCompanyName(corp.getCorpName());
        //获取锁
        String lockKey = corpId +"-" + employeeId + "-" + contactId;
        boolean lock = RedisUtil.getLock(lockKey);
        try{
            if(!lock) {
                return R.ok(vo);
            }

            //查询一客一码记录
            ContactUniqueQrCode cuqc = this.getOne(Wrappers.<ContactUniqueQrCode>lambdaQuery()
                    .eq(ContactUniqueQrCode::getEmployeeId, employeeId)
                    .eq(ContactUniqueQrCode::getContactId, contactId),false);

            Map result = null;
            String state = "";

            //没有记录则生成联系我二维码,这里使用邀请客户、企业成员主键id作为专属二维码标识state
            state = Constant.UQC_PREFIX + contactId + "-" + employeeId;
//                result = generateLocalQrCode(corpId, wxUserId, state);
            result = handleLocalQrCode(null, corpId, wxUserId, state, vo);

            boolean isChangeQrCode = (boolean)result.get("isChangeQrCode");
            String localQrCode = (String)result.get("localQrCode");
            String configId = (String)result.get("configId");

            boolean isChangeUnique = false;
            String uniqueQrCode = "";

            boolean flag = false;
            if(cuqc == null) {
                //初次创建
                cuqc = new ContactUniqueQrCode();
                cuqc.setContactId(contactId);
                cuqc.setEmployeeId(employeeId);
                cuqc.setConfigId(configId);
                cuqc.setLocalQrCode(localQrCode);
                cuqc.setState(state);
                cuqc.setUniqueQrCode(vo.getUniqueQrCode());
                cuqc.setFlag(1);
                flag = this.save(cuqc);
                vo.setCodeId(cuqc.getId());
                return R.ok(vo);
            } else {
                cuqc.setContactId(contactId);
                cuqc.setEmployeeId(employeeId);
                cuqc.setConfigId(configId);
                cuqc.setLocalQrCode(localQrCode);
                cuqc.setState(state);
                cuqc.setUniqueQrCode(vo.getUniqueQrCode());
                cuqc.setFlag(1);
                flag = this.updateById(cuqc);
                vo.setCodeId(cuqc.getId());
                return R.ok(vo);
            }
        }catch (Exception e) {
            log.error("创建专属二维码失败",e);
        }
        finally {
            if(lock) {
                //释放锁
                RedisUtil.del(lockKey);
            }
        }
        return R.ok(vo);
    }

//    @Transactional
//    public R getUniqueQrCode1(ContactUniqueQrCodeDto dto) {
//        //校验操作类型
//        Integer operType = dto.getOperType();
//        checkOperation(operType);
//
//        Integer corpId = CorpContextHolder.getCorpId();
//        String wxUserId = dto.getWxUserId();
//        String wxExternalUserid = dto.getWxExternalUserid();
//
//        //获取企业
//        CorpEntity corp = corpService.getById(corpId);
//        //获取企业成员
//        WorkEmployeeEntity employee = workEmployeeService.getWorkEmployeeByCorpIdAndWxUserId(corpId, wxUserId);
//        if(employee == null || employee.getStatus() != 1) {
//            throw new CheckedException("企业成员不存在");
//        }
//        Integer employeeId = employee.getId();
//        //获取外部联系人
//        WorkContactEntity contactEntity = contactService.getOne(Wrappers.<WorkContactEntity>lambdaQuery()
//                .eq(WorkContactEntity::getWxExternalUserid,wxExternalUserid)
//                .eq(WorkContactEntity::getCorpId,corpId),false);
//        if(contactEntity == null) {
//            throw new CheckedException("外部联系人不存在");
//        }
//        Integer contactId = contactEntity.getId();
//
//        ContactUniqueQrCodeVo vo = new ContactUniqueQrCodeVo();
//        vo.setEmpName(employee.getName());
//        vo.setAvatar(employee.getAvatar());
//        vo.setCompanyName(corp.getCorpName());
//        //获取锁
//        String lockKey = corpId +"-" + employeeId + "-" + contactId;
//        boolean lock = RedisUtil.getLock(lockKey);
//        try{
//            if(!lock) {
//                return R.ok(vo);
//            }
//
//            //查询一客一码记录
//            ContactUniqueQrCode cuqc = this.getOne(Wrappers.<ContactUniqueQrCode>lambdaQuery()
//                    .eq(ContactUniqueQrCode::getEmployeeId, employeeId)
//                    .eq(ContactUniqueQrCode::getContactId, contactId),false);
//
//            Map result = null;
//            String state = "";
//            if(cuqc == null) {
//                //没有记录则生成联系我二维码,这里使用邀请客户、企业成员主键id作为专属二维码标识state
//                state = Constant.UQC_PREFIX + contactId + "-" + employeeId;
////                result = generateLocalQrCode(corpId, wxUserId, state);
//                result = handleLocalQrCode(null, corpId, wxUserId, state, vo);
//            } else /* if (cuqc.getFlag().equals(1)) */{
////                result = generateQrCode(corpId,null,null, cuqc.getConfigId());
//                result = new HashMap<>();
//                result.put("localQrCode", cuqc.getLocalQrCode());
//                result.put("configId", cuqc.getConfigId());
//                result.put("isChangeQrCode", Boolean.TRUE);
//            }/* else {
//                //已存在直接获取
////                result = getLocalQrCode(cuqc, corpId);
//                result = handleLocalQrCode(cuqc, corpId, null, null, vo);
//            }*/
//
//            boolean isChangeQrCode = (boolean)result.get("isChangeQrCode");
//            String localQrCode = (String)result.get("localQrCode");
//            String configId = (String)result.get("configId");
//
//            boolean isChangeUnique = false;
//            String uniqueQrCode = "";
//
//            boolean flag = false;
//            if(cuqc == null) {
//                //初次创建
//                cuqc = new ContactUniqueQrCode();
//                cuqc.setContactId(contactId);
//                cuqc.setEmployeeId(employeeId);
//                cuqc.setConfigId(configId);
//                cuqc.setLocalQrCode(localQrCode);
//                cuqc.setState(state);
//                cuqc.setUniqueQrCode(vo.getUniqueQrCode());
//                cuqc.setFlag(1);
//                flag = this.save(cuqc);
//                vo.setCodeId(cuqc.getId());
//                return R.ok(vo);
//            }
//
//            ContactUniqueQrCodeBo bo = new ContactUniqueQrCodeBo();
//            bo.setName(employee.getName());
//            bo.setAvatar(employee.getAvatar());
//            bo.setCompany(corp.getCorpName());
//            bo.setLocalQrCode(localQrCode);
//            bo.setDesc("扫一扫，加我企业微信");
//            bo.setFileKey(cuqc.getFlag().equals(1) ? "" : cuqc.getUniqueQrCode().replace(config.getAccessPath(), ""));
//            //判断操作类型
//            if(operType == 1) {
//                //更新头像重新生成客户专属二维码
//                uniqueQrCode = generateUniqueQrCode(bo);
//                isChangeUnique = Boolean.TRUE;
//            } else {
//                //查询客户专属二维码
//                if(cuqc.getFlag().equals(1)) {
////                    uniqueQrCode = generateUniqueQrCode(bo);
//                    vo.setType(1);
//                    vo.setMessage("未获取到上传文件");
//                    vo.setUniqueQrCode(cuqc.getUniqueQrCode());
//                    vo.setCodeId(cuqc.getId());
//                    return R.ok(vo);
//                } else {
//                    uniqueQrCode = cuqc.getUniqueQrCode();
//                    //校验二维码文件是否存在
//                    File uniqueQrCodeFile = FilesUtil.getFileByURI(uniqueQrCode);
//                    if(!uniqueQrCodeFile.exists()) {
//                        //不存在重新生成
////                        uniqueQrCode = generateUniqueQrCode(bo);
//                        vo.setType(1);
//                        vo.setMessage("未获取到上传文件");
//                        vo.setUniqueQrCode(cuqc.getUniqueQrCode());
//                        vo.setCodeId(cuqc.getId());
//                        return R.ok(vo);
//                    }
//                }
//            }
//
//            //上传客户专属二维码至临时素材
//            String mediaId = null;
//            if(isChangeUnique) {
//                File uniqueFile = FilesUtil.getFileByURI(uniqueQrCode);
//                mediaId = WxApiUtils.uploadImageToTemps(corpId, uniqueFile,"image");
//            }
//
//            if(cuqc.getFlag().equals(1)) {
//                //初次创建
//                cuqc.setUniqueQrCode(uniqueQrCode);
//                cuqc.setMediaId(mediaId);
//                cuqc.setFlag(2);
//                flag = this.updateById(cuqc);
//            } else {
//                mediaId = cuqc.getMediaId();
//                //更新
//                if(isChangeQrCode || isChangeUnique) {
//                    cuqc.setLocalQrCode(localQrCode);
//                    cuqc.setUniqueQrCode(uniqueQrCode);
//                    cuqc.setMediaId(mediaId);
//                    flag = this.updateById(cuqc);
//                } else {
//                    //仅查询
//                    //校验mediaId是否过期,过期则重新上传
//                    String respJson = WxApiUtils.getFromTemp(corpId, mediaId);
//                    if(respJson == null) {
//                        File uniqueFile = FilesUtil.getFileByURI(cuqc.getUniqueQrCode());
//                        mediaId = WxApiUtils.uploadImageToTemps(corpId, uniqueFile,"image");
//                        cuqc.setUniqueQrCode(mediaId);
//                        flag = this.updateById(cuqc);
//                    }else {
//                        flag = Boolean.TRUE;
//                    }
//                }
//
//            }
//
//            vo.setUniqueQrCode(uniqueQrCode);
//            vo.setMediaId(mediaId);
//            if(!flag) {
//                vo.setUniqueQrCode("");
//                log.error("创建专属二维码失败");
//            }
//        }catch (Exception e) {
//            log.error("创建专属二维码失败",e);
//        }
//        finally {
//            if(lock) {
//                //释放锁
//                RedisUtil.del(lockKey);
//            }
//        }
//
//        return R.ok(vo);
//    }

    @Override
    public void getUniqueQrCodeWeb(ContactUniqueQrCodeDto dto, ContactUniqueQrCodeWebVo vo1) {
        vo1.setType(2);
        vo1.setScene("2");
        vo1.setWxDepartmentIdList(null);

        //校验操作类型
        Integer operType = dto.getOperType();
        checkOperation(operType);

        Integer corpId = CorpContextHolder.getCorpId();
        String wxUserId = dto.getWxUserId();
        String wxExternalUserid = dto.getWxExternalUserid();

        List<String> wxUsers = new ArrayList<>();
        wxUsers.add(wxUserId);
        vo1.setWxUserIdList(wxUsers);

        //获取企业
        CorpEntity corp = corpService.getById(corpId);
        //获取企业成员
        WorkEmployeeEntity employee = workEmployeeService.getWorkEmployeeByCorpIdAndWxUserId(corpId, wxUserId);
        if(employee == null || employee.getStatus() != 1) {
            throw new CheckedException("企业成员不存在");
        }
        Integer employeeId = employee.getId();
        //获取外部联系人
        WorkContactEntity contactEntity = contactService.getOne(Wrappers.<WorkContactEntity>lambdaQuery()
                .eq(WorkContactEntity::getWxExternalUserid,wxExternalUserid)
                .eq(WorkContactEntity::getCorpId,corpId),false);
        if(contactEntity == null) {
            throw new CheckedException("外部联系人不存在");
        }
        Integer contactId = contactEntity.getId();

        ContactUniqueQrCodeVo vo = new ContactUniqueQrCodeVo();
        //获取锁
        String lockKey = corpId +"-" + employeeId + "-" + contactId;
        boolean lock = RedisUtil.getLock(lockKey);
        try{
            if(!lock) {
                return ;
            }

            //查询一客一码记录
            ContactUniqueQrCode cuqc = this.getOne(Wrappers.<ContactUniqueQrCode>lambdaQuery()
                    .eq(ContactUniqueQrCode::getEmployeeId, employeeId)
                    .eq(ContactUniqueQrCode::getContactId, contactId),false);
            String state = Constant.UQC_PREFIX + contactId + "-" + employeeId;
            vo1.setState(state);

            vo1.setName(employee.getName());
            vo1.setAvatar(employee.getAvatar());
            vo1.setCompany(corp.getCorpName());
            vo1.setDesc("扫一扫，加我企业微信");
        } catch (Exception e) {
            log.error("创建专属二维码失败", e);
        }
        finally {
            if(lock) {
                //释放锁
                RedisUtil.del(lockKey);
            }
        }
        return ;
    }

    /**
     * 校验操作类型
     * @param operType
     */
    private void checkOperation(Integer operType) {
        if(operType == 0 || operType == 1) {
            return;
        }
        throw new CheckedException("非法操作");
    }

    /**
     * 创建客户专属二维码
     * @return
     */
    private String generateUniqueQrCode(ContactUniqueQrCodeBo cuqcb) throws IOException{
        //获取联系我二维码
        File qrCodeFile = FilesUtil.getFileByURI(cuqcb.getLocalQrCode());
        BufferedImage qrCodeImage = ImageIO.read(qrCodeFile);

        //获取头像
//        File avatarFile = FilesUtil.getFileByURI(cuqcb.getAvatar());
//        BufferedImage avatarImage = ImageIO.read(avatarFile);

        // 透明底的图片
//        BufferedImage bi2 = new BufferedImage(avatarImage.getWidth(), avatarImage.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
//        Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, avatarImage.getWidth(), avatarImage.getHeight());
//        Graphics2D g2 = bi2.createGraphics();
//        g2.setClip(shape);
//        // 使用 setRenderingHint 设置抗锯齿
//        g2.drawImage(avatarImage, 0, 0, null);
//        // 设置颜色
//        g2.setBackground(Color.green);
//        g2.dispose();
//        avatarImage = bi2;

        //获取二维码头像
//        BufferedImage qrAvatarImage = ImageIO.read(avatarFile);

        //获取专属二维码背景
        BufferedImage image = new BufferedImage(Constant.QR_BG_WIDTH, Constant.QR_BG_HEIGTH,BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = image.createGraphics();

        //画笔属性设置
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        //绘制专属二维码
        //绘制背景
        Color c = g.getColor();
        g.setColor(new Color(255, 255, 255, 255));
        g.fillRect(0,0, Constant.QR_BG_WIDTH, Constant.QR_BG_HEIGTH);
        g.setColor(c);
        //绘制头像
        g.drawImage(null, Constant.AVATAR_X_OFFSET, Constant.AVATAR_Y_OFFSET, Constant.AVATAR_WIDTH, Constant.AVATAR_HEIGHT, null);
        //绘制二维码
        g.drawImage(qrCodeImage, Constant.QR_X_OFFSET, Constant.QR_Y_OFFSET, Constant.QR_WIDTH, Constant.QR_HEIGTH, null);
        //绘制二维码内头像
//        g.drawImage(qrAvatarImage,Constant.QR_AVATAR_X_OFFSET,Constant.QR_AVATAR_Y_OFFSET,Constant.AVATAR_WIDTH,Constant.AVATAR_HEIGHT,null);
        //绘制客户名称
        Font font1 = new Font("黑体", Font.BOLD, 26);
        g.setColor(Color.BLACK);
        g.setFont(font1);
        g.drawString(cuqcb.getName(), Constant.NAME_X_OFFSET, Constant.NAME_Y_OFFSET);
        //绘制企业名称
        Font font2 = new Font("黑体", Font.PLAIN, 16);
        g.setFont(font2);
        g.setColor(Color.BLACK);
        g.drawString(cuqcb.getCompany(), Constant.COMPANY_X_OFFSET, Constant.COMPANY_Y_OFFSET);
        //绘制二维码描述
        Font font3 = new Font("黑体", Font.PLAIN, 12);
        g.setFont(font3);
        g.setColor(Color.BLACK);
        g.drawString(cuqcb.getDesc(), Constant.QR_DESC_X_OFFSET, Constant.QR_DESC_Y_OFFSET);
        g.dispose();

        //保存专属二维码
        String fileKey = StrUtil.isEmpty(cuqcb.getFileKey()) ? getUniqueQrCodeFileKey() : cuqcb.getFileKey();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image,"png", baos);
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        SysFileVo vo = FilesUtil.uploadFile(bais, fileKey, true, true);
        log.info("生成专属二维码成功");

        String uniqueQrCode = vo.getUrl();
        return uniqueQrCode;
    }

    private String generateUniqueQrCode(ContactUniqueQrCodeBo cuqcb, boolean isUpload) throws IOException{
        //获取联系我二维码
        File qrCodeFile = FilesUtil.getFileByURI(cuqcb.getLocalQrCode());
        BufferedImage qrCodeImage = ImageIO.read(qrCodeFile);

        //获取头像
//        File avatarFile = FilesUtil.getFileByURI(cuqcb.getAvatar());
//        BufferedImage avatarImage = ImageIO.read(avatarFile);

        // 透明底的图片
//        BufferedImage bi2 = new BufferedImage(avatarImage.getWidth(), avatarImage.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
//        Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, avatarImage.getWidth(), avatarImage.getHeight());
//        Graphics2D g2 = bi2.createGraphics();
//        g2.setClip(shape);
//        // 使用 setRenderingHint 设置抗锯齿
//        g2.drawImage(avatarImage, 0, 0, null);
//        // 设置颜色
//        g2.setBackground(Color.green);
//        g2.dispose();
//        avatarImage = bi2;

        //获取二维码头像
//        BufferedImage qrAvatarImage = ImageIO.read(avatarFile);

        //获取专属二维码背景
        BufferedImage image = new BufferedImage(Constant.QR_BG_WIDTH, Constant.QR_BG_HEIGTH,BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = image.createGraphics();

        //画笔属性设置
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        //绘制专属二维码
        //绘制背景
        Color c = g.getColor();
        g.setColor(new Color(255, 255, 255, 255));
        g.fillRect(0,0, Constant.QR_BG_WIDTH, Constant.QR_BG_HEIGTH);
        g.setColor(c);
        //绘制头像
        g.drawImage(null, Constant.AVATAR_X_OFFSET, Constant.AVATAR_Y_OFFSET, Constant.AVATAR_WIDTH, Constant.AVATAR_HEIGHT, null);
        //绘制二维码
        g.drawImage(qrCodeImage, Constant.QR_X_OFFSET, Constant.QR_Y_OFFSET, Constant.QR_WIDTH, Constant.QR_HEIGTH, null);
        //绘制二维码内头像
//        g.drawImage(qrAvatarImage,Constant.QR_AVATAR_X_OFFSET,Constant.QR_AVATAR_Y_OFFSET,Constant.AVATAR_WIDTH,Constant.AVATAR_HEIGHT,null);
        //绘制客户名称
        Font font1 = new Font("黑体", Font.BOLD, 26);
        g.setColor(Color.BLACK);
        g.setFont(font1);
        g.drawString(cuqcb.getName(), Constant.NAME_X_OFFSET, Constant.NAME_Y_OFFSET);
        //绘制企业名称
        Font font2 = new Font("黑体", Font.PLAIN, 16);
        g.setFont(font2);
        g.setColor(Color.BLACK);
        g.drawString(cuqcb.getCompany(), Constant.COMPANY_X_OFFSET, Constant.COMPANY_Y_OFFSET);
        //绘制二维码描述
        Font font3 = new Font("黑体", Font.PLAIN, 12);
        g.setFont(font3);
        g.setColor(Color.BLACK);
        g.drawString(cuqcb.getDesc(), Constant.QR_DESC_X_OFFSET, Constant.QR_DESC_Y_OFFSET);
        g.dispose();

        //保存专属二维码
        String fileKey = StrUtil.isEmpty(cuqcb.getFileKey()) ? getUniqueQrCodeFileKey() : cuqcb.getFileKey();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image,"png", baos);
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        SysFileVo vo = FilesUtil.uploadFile(bais, fileKey, true, isUpload);
        log.info("生成专属二维码成功");

        String uniqueQrCode = vo.getUrl();
        return uniqueQrCode;
    }

    /**
     * 生成本地[联系我]二维码
     * @return
     */
    private Map generateLocalQrCode(Integer corpId, String wxUserId, String state, ContactUniqueQrCodeVo vo) {
        return handleLocalQrCode(null, corpId, wxUserId, state, vo);
    }

    /**
     * 已存在获取本地[联系我]二维码
     * @param cuqc
     * @param corpId
     * @return
     */
    private Map getLocalQrCode(ContactUniqueQrCode cuqc, Integer corpId, ContactUniqueQrCodeVo vo) {
        return handleLocalQrCode(cuqc, corpId, null, null, vo);
    }


    /**
     * 处理本地[联系我]二维码
     * @return
     */
    private Map handleLocalQrCode(ContactUniqueQrCode cuqc, Integer corpId, String wxUserId, String state, ContactUniqueQrCodeVo vo) {
        boolean isUpload = true;
        String localQrCode = "";
        Map result = null;

        boolean isChangeQrCode = false;
        if(cuqc == null) {
            isUpload = false;
            //第一次生成
            result = generateQrCode(corpId, wxUserId, state, null);
            vo.setType(1);
            vo.setMessage("没有联系我二维码，请前端代为获取");
            vo.setUniqueQrCode((String) result.get("qrCode"));
            isChangeQrCode = Boolean.TRUE;
            log.info(corpId + "-" + wxUserId + "-" + state + "-联系我二维码创建成功");
        } else {
            //已生成
            localQrCode = cuqc.getLocalQrCode();
            File qrCodeFile = FilesUtil.getFileByURI(localQrCode);
            //验证二维码文件是否存在
            if(!qrCodeFile.exists()) {
                //不存在再一次查询
                result = generateQrCode(corpId,null,null, cuqc.getConfigId());
                isChangeQrCode = Boolean.TRUE;
                log.info(corpId + "-" + cuqc.getConfigId() + "-联系我二维码二次获取成功");
            } else {
                //存在直接返回
                result = new HashMap();
                result.put("localQrCode", localQrCode);
                result.put("isChangeQrCode", isChangeQrCode);
                return result;
            }
        }
        //将联系我二维码上传到本地文件系统
        SysFileVo fileVo = uploadQrCode(result, isUpload);

        vo.setUpLoadUrl((String) result.get("fileKey"));
        result.put("localQrCode", fileVo.getUrl());
        result.put("isChangeQrCode", isChangeQrCode);
        return result;
    }

    /**
     * 生成[联系我]二维码
     * @param corpId
     * @param wxUserId
     * @param state
     * @param configId
     * @return
     */
    private Map generateQrCode(Integer corpId, String wxUserId, String state, String configId) {
        //校验必要字段
        if(corpId == null) {
            throw new CheckedException("企业id不能为空");
        }

        Map<String, String> result = null;
        JSONObject json = null;
        String respJson = "";

        if(StrUtil.isEmpty(configId)) {
            //校验必要字段
            if(StrUtil.isEmpty(state)) {
                throw new CheckedException("联系我二维码标识不能为空");
            }
            if(StrUtil.isEmpty(wxUserId)) {
                throw new CheckedException("企业微信成员id不能为空");
            }
            //重新生成
            List<String> wxUsers = new ArrayList<>();
            wxUsers.add(wxUserId);
            respJson = WxApiUtils.requestCreateContactWay(corpId, 2, Boolean.TRUE, state, wxUsers, null);
            if(respJson == null) {
                throw new CheckedException("获取[联系我]二维码失败");
            }
            json = JSONUtil.parseObj(respJson);
            result = new HashMap<>();
            result.put("configId", json.getStr("config_id"));
            result.put("qrCode", json.getStr("qr_code"));
        } else {
            //已生成，通过configId查询
            respJson = WxApiUtils.requestGetContactWay(corpId, configId);
            if(respJson == null) {
                throw new CheckedException("获取[联系我]二维码失败");
            }
            json = JSONUtil.parseObj(respJson);
            result = new HashMap<>();
            result.put("qrCode", json.getJSONObject("contact_way").getStr("qr_code"));
        }
        return result;
    }

    /**
     * 联系我二维码上传
     * @param result
     * @return
     */
    private SysFileVo uploadQrCode(Map result, Boolean isUpload) {
        SysFileVo fileVo = new SysFileVo();
        try {
            String qrCode = (String)result.get("qrCode");
            String fileKey = getLocalQrCodeFileKey();
            result.put("fileKey", fileKey);
            fileVo = FilesUtil.uploadFileByURL(qrCode, fileKey, true, isUpload);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return fileVo;
    }

    /**
     * 获取本地联系我二维码文件key
     * @return
     */
    private String getLocalQrCodeFileKey() {
        return Constant.UQC_DIR + FilesUtil.getRandomFileName("png");
    }

    private String getUniqueQrCodeFileKey() {
        return Constant.UQC_DIR + FilesUtil.getRandomFileName("png");
    }

    @Override
    public R<ContactUniqueQrCodeVo> upload(Integer codeId, MultipartFile file) {
        ContactUniqueQrCodeVo vo = new ContactUniqueQrCodeVo();
        Integer corpId = CorpContextHolder.getCorpId();
        try {
            String fileKey = getLocalQrCodeFileKey();
            String uniqueQrCode = "/mfs" + fileKey;
            FilesUtil.uploadFile(file, fileKey, true);
            ContactUniqueQrCode contactUniqueQrCode = new ContactUniqueQrCode();
            contactUniqueQrCode.setId(codeId);
            contactUniqueQrCode.setFlag(2);
            contactUniqueQrCode.setUniqueQrCode(uniqueQrCode);

            String mediaId = null;
            File uniqueFile = FilesUtil.getFileByURI(uniqueQrCode);
            mediaId = WxApiUtils.uploadImageToTemps(corpId, uniqueFile,"image");
            contactUniqueQrCode.setMediaId(mediaId);
            this.baseMapper.updateById(contactUniqueQrCode);

            vo.setMediaId(mediaId);
            vo.setUniqueQrCode(uniqueQrCode);
            return R.ok(vo);
        } catch (Exception e) {
            return R.failed();
        }
    }

}
